package com.client;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.FocusEvent;
import com.google.gwt.event.dom.client.FocusHandler;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.event.logical.shared.OpenEvent;
import com.google.gwt.event.logical.shared.OpenHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DecoratorPanel;
import com.google.gwt.user.client.ui.DisclosurePanel;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.MultiWordSuggestOracle;
import com.google.gwt.user.client.ui.SuggestBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.datepicker.client.DateBox;
import com.google.gwt.visualization.client.DataTable;
import com.google.gwt.visualization.client.Query;
import com.google.gwt.visualization.client.QueryResponse;
import com.google.gwt.visualization.client.Query.Callback;

public class PLSearch extends SlidePanel {
	public DecoratorPanel dplSearch;
	public FlexTable ftSearch;
	public SuggestBox sbTags;
	public Button btnSearch;
	public DisclosurePanel plAdv;
	public Grid gAdvSearch;
	public ListBox lbTags;
	public DateBox dbBegin;
	public DateBox dbEnd;
	public TextBox tbDfmt;
	public TextBox tbX;
	public TextBox tbY;
	public Button btnAdvSearch;
	
	protected void onFirstShow() {
  	this.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
  	this.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);

  	dplSearch = new DecoratorPanel();
  	ftSearch = new FlexTable();
  	
  	btnSearch = new Button("Search", new ClkSearch());
  	plAdv = new DisclosurePanel("Advanced");

  	this.add(dplSearch);
  	dplSearch.add(ftSearch);
  	ftSearch.setHTML(0, 0, "Tags:");
  	ftSearch.setHTML(0, 1, "Loading...");
  	ftSearch.setWidget(0, 2, btnSearch);
  	ftSearch.getFlexCellFormatter().setColSpan(1, 0, 3);
  	ftSearch.setWidget(1, 0, plAdv);
  	plAdv.addOpenHandler(new OpenHandlerAdv());
  	
  	Query.create(CNStatsFront.baseURL + "queryhistory").send(new CBQueryHistory());
	}
}

final class OpenHandlerAdv implements OpenHandler<DisclosurePanel> {
	public void onOpen(OpenEvent<DisclosurePanel> event) {
		if(null == CNStatsFront.get().plSearch.plAdv.getContent()) {
			CNStatsFront.get().plSearch.gAdvSearch = new Grid(7, 2);
			CNStatsFront.get().plSearch.lbTags = new ListBox(true);
			CNStatsFront.get().plSearch.dbBegin = new DateBox();
			CNStatsFront.get().plSearch.dbEnd = new DateBox();
			CNStatsFront.get().plSearch.tbDfmt = new TextBox();
			CNStatsFront.get().plSearch.tbX = new TextBox();
			CNStatsFront.get().plSearch.tbY = new TextBox();
			CNStatsFront.get().plSearch.btnAdvSearch = new Button("Advanced Search", new ClkAdvSearch());
					
//			CNStatsFront.get().plSearch.ftSearch.setBorderWidth(2);
//			CNStatsFront.get().plSearch.gAdvSearch.setBorderWidth(2);
			
			CNStatsFront.get().plSearch.lbTags.addItem("Loading...");
			CNStatsFront.get().plSearch.gAdvSearch.setHTML(0, 0, "Tags:");
			CNStatsFront.get().plSearch.gAdvSearch.setWidget(0, 1, CNStatsFront.get().plSearch.lbTags);
			CNStatsFront.get().plSearch.lbTags.setVisibleItemCount(10);
			CNStatsFront.get().plSearch.gAdvSearch.setHTML(1, 0, "Begin:");
			CNStatsFront.get().plSearch.gAdvSearch.setWidget(1, 1, CNStatsFront.get().plSearch.dbBegin);
			CNStatsFront.get().plSearch.gAdvSearch.setHTML(2, 0, "End:");
			CNStatsFront.get().plSearch.gAdvSearch.setWidget(2, 1, CNStatsFront.get().plSearch.dbEnd);
			CNStatsFront.get().plSearch.gAdvSearch.setHTML(3, 0, "Format:");
			CNStatsFront.get().plSearch.gAdvSearch.setWidget(3, 1, CNStatsFront.get().plSearch.tbDfmt);
			CNStatsFront.get().plSearch.gAdvSearch.setHTML(4, 0, "X:");
			CNStatsFront.get().plSearch.gAdvSearch.setWidget(4, 1, CNStatsFront.get().plSearch.tbX);
			CNStatsFront.get().plSearch.gAdvSearch.setHTML(5, 0, "Y:");
			CNStatsFront.get().plSearch.gAdvSearch.setWidget(5, 1, CNStatsFront.get().plSearch.tbY);
			CNStatsFront.get().plSearch.gAdvSearch.setWidget(6, 1, CNStatsFront.get().plSearch.btnAdvSearch);
			
			String width = "215px";
			CNStatsFront.get().plSearch.lbTags.setWidth(width);
			CNStatsFront.get().plSearch.dbBegin.setWidth(width);
			CNStatsFront.get().plSearch.dbEnd.setWidth(width);
			CNStatsFront.get().plSearch.tbDfmt.setWidth(width);
			CNStatsFront.get().plSearch.tbX.setWidth(width);
			CNStatsFront.get().plSearch.tbY.setWidth(width);
	  	
			CNStatsFront.get().plSearch.gAdvSearch.getCellFormatter().setVerticalAlignment(0, 0, HasVerticalAlignment.ALIGN_TOP);
			CNStatsFront.get().plSearch.gAdvSearch.getCellFormatter().setHorizontalAlignment(0, 0, HasHorizontalAlignment.ALIGN_RIGHT);
			CNStatsFront.get().plSearch.gAdvSearch.getCellFormatter().setHorizontalAlignment(1, 0, HasHorizontalAlignment.ALIGN_RIGHT);
			CNStatsFront.get().plSearch.gAdvSearch.getCellFormatter().setHorizontalAlignment(2, 0, HasHorizontalAlignment.ALIGN_RIGHT);
			CNStatsFront.get().plSearch.gAdvSearch.getCellFormatter().setHorizontalAlignment(3, 0, HasHorizontalAlignment.ALIGN_RIGHT);
			CNStatsFront.get().plSearch.gAdvSearch.getCellFormatter().setHorizontalAlignment(4, 0, HasHorizontalAlignment.ALIGN_RIGHT);
			CNStatsFront.get().plSearch.gAdvSearch.getCellFormatter().setHorizontalAlignment(5, 0, HasHorizontalAlignment.ALIGN_RIGHT);
			CNStatsFront.get().plSearch.gAdvSearch.getCellFormatter().setHorizontalAlignment(6, 1, HasHorizontalAlignment.ALIGN_RIGHT);
	  	
			CNStatsFront.get().plSearch.plAdv.setContent(CNStatsFront.get().plSearch.gAdvSearch);
			CNStatsFront.get().plSearch.plAdv.setAnimationEnabled(true);
	  	
	  	Query.create(CNStatsFront.baseURL + "querytags").send(new CBQueryTags());
		}
	}
}

final class ClkSearch implements ClickHandler {
	public void onClick(ClickEvent event) {
		String searchURL = 
			CNStatsFront.baseURL + "querystats?tags=" + CNStatsFront.get().plSearch.sbTags.getText().toLowerCase();
		Query.create(searchURL).send(new CBQueryStats());
	}
}

final class ClkAdvSearch implements ClickHandler {
	public void onClick(ClickEvent event) {
		CNStatsFront.get().plSearch.plAdv.setOpen(false);
		
		String tags = "";
		for(int i=CNStatsFront.get().plSearch.lbTags.getSelectedIndex();
		i<CNStatsFront.get().plSearch.lbTags.getItemCount();i++) {
			if(true == CNStatsFront.get().plSearch.lbTags.isItemSelected(i)) {
				if(tags.length()>0) tags += " ";
				tags += CNStatsFront.get().plSearch.lbTags.getValue(i);
			}
		}
		String searchURL = CNStatsFront.baseURL + "querystats?tags=" + tags;
		
		DateTimeFormat dfmt = DateTimeFormat.getFormat("yyyyMMddHHmmss");
		if(null != CNStatsFront.get().plSearch.dbBegin.getValue()) {
			searchURL += "&begin=" + dfmt.format(
					CNStatsFront.get().plSearch.dbBegin.getValue());
		}
		if(null != CNStatsFront.get().plSearch.dbEnd.getValue()) {
			searchURL += "&end=" + dfmt.format(
					CNStatsFront.get().plSearch.dbEnd.getValue());
		}
		if(CNStatsFront.get().plSearch.tbDfmt.getValue().length() > 0) {
			searchURL += "&dfmt=" + CNStatsFront.get().plSearch.tbDfmt.getValue();
		}
		if(CNStatsFront.get().plSearch.tbX.getValue().length() > 0) {
			searchURL += "&x=" + CNStatsFront.get().plSearch.tbX.getValue();
		}
		if(CNStatsFront.get().plSearch.tbY.getValue().length() > 0) {
			searchURL += "&y=" + CNStatsFront.get().plSearch.tbY.getValue();
		}
		Query.create(searchURL).send(new CBQueryStats());
	}
}

final class CBQueryStats implements Callback {
	public void onResponse(QueryResponse response) {
		if (response.isError()) {
			DialogInfo.info("Information", response.getMessage()+":"+response.getDetailedMessage());
		} else {
			// Get the data from the QueryResponse.
			DataTable data = response.getDataTable();
			CNStatsFront.get().plCharts.setData(data);
			CNStatsFront.get().plCharts.show();
			CNStatsFront.get().plCharts.draw();
		}
		CNStatsFront.get().plSearch.sbTags.setText("e.g. China GDP");
	}
}

final class CBQueryHistory implements Callback {
	public void onResponse(QueryResponse response) {
		if (response.isError()) {
			// TODO: Don't need pop up message.
			return;
		} else {
			DataTable data = response.getDataTable();
			
			MultiWordSuggestOracle oracle = new MultiWordSuggestOracle();
			for(int i=0; i<data.getNumberOfRows(); i++) {
				oracle.add(data.getValueString(i, 0));
			}
			CNStatsFront.get().plSearch.sbTags = new SuggestBox(oracle);
			CNStatsFront.get().plSearch.sbTags.setText("e.g. China GDP");
			CNStatsFront.get().plSearch.sbTags.getTextBox().addFocusHandler(new FocusHandler() {
				public void onFocus(FocusEvent event) {
					CNStatsFront.get().plSearch.sbTags.setText("");
				}					
			});
			CNStatsFront.get().plSearch.sbTags.getTextBox().addKeyPressHandler(new KeyPressHandler() {
				public void onKeyPress(KeyPressEvent event) {
					//Get return key
					if( CNStatsFront.get().plSearch.sbTags.getText().length() > 0 &&
							13 == event.getCharCode()) {
						CNStatsFront.get().plSearch.btnSearch.click();
					}
				}
			});
			CNStatsFront.get().plSearch.sbTags.setAnimationEnabled(true);
			CNStatsFront.get().plSearch.ftSearch.setWidget(0, 1, CNStatsFront.get().plSearch.sbTags);
		}
	}
}

final class CBQueryTags implements Callback {
	public void onResponse(QueryResponse response) {
		if (response.isError()) {
			// TODO: Don't need pop up message.
			return;
		} else {
			// Get the data from the QueryResponse.
			DataTable data = response.getDataTable();
			
			CNStatsFront.get().plSearch.lbTags.clear();
			for(int i=0; i<data.getNumberOfRows(); i++) {
				CNStatsFront.get().plSearch.lbTags.addItem(data.getValueString(i, 0));
			}
		}
	}
}
